package com.autumn.web.configure;

import org.springframework.beans.factory.config.RuntimeBeanReference;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.GenericBeanDefinition;
import org.springframework.core.annotation.AnnotationAttributes;
import org.springframework.core.type.AnnotationMetadata;

import com.autumn.spring.boot.bean.AbstractImportBeanDefinitionRegister;
import com.autumn.spring.boot.bean.BeanDefinitionRegisterManager;
import com.autumn.util.ExceptionUtils;
import com.autumn.util.TypeUtils;
import com.autumn.web.annotation.EnableAutumnApiResponseBody;
import com.autumn.web.handlers.ApiResponseBodyHandler;
import com.autumn.web.handlers.DefaultErrorInfoResultHandler;
import com.autumn.web.handlers.IErrorInfoResultHandler;

/**
 * Api 响应体扫描配置
 * 
 * @author 老码农
 *
 *         2018-01-15 09:17:57
 */
public class ApiResponseBodyBeanDefinitionRegister extends AbstractImportBeanDefinitionRegister {

	@Override
	public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
		AnnotationAttributes annoAttrs = AnnotationAttributes
				.fromMap(importingClassMetadata.getAnnotationAttributes(EnableAutumnApiResponseBody.class.getName()));
		Class<? extends IErrorInfoResultHandler> errorInfoResultHandlerClass = annoAttrs
				.getClass(EnableAutumnApiResponseBody.ERROR_INFO_RESULT_HANDLER_CLASS_ATTRIBUTE_NAME);
		if (errorInfoResultHandlerClass == null) {
			errorInfoResultHandlerClass = DefaultErrorInfoResultHandler.class;
		} else {
			if (TypeUtils.isAbstract(errorInfoResultHandlerClass)) {
				ExceptionUtils.throwConfigureException("类型 " + errorInfoResultHandlerClass + " 不能是抽象或接口类。");
			}
		}
		Object status = annoAttrs.get(EnableAutumnApiResponseBody.ERROR_RESPONSE_STATUS_ATTRIBUTE_NAME);		
		BeanDefinitionRegisterManager regManager = new BeanDefinitionRegisterManager(this.getEnvironment(),
				this.getResourceLoader(), registry);
		GenericBeanDefinition definition;
		String handlerBeanName = regManager.generateBeanName(errorInfoResultHandlerClass);
		if (!registry.containsBeanDefinition(handlerBeanName)) {
			definition = regManager.createBeanDefinition(errorInfoResultHandlerClass, null, null, null);
			regManager.registerBean(handlerBeanName, definition);
		}
		String apiResponseBeanName = regManager.generateBeanName(ApiResponseBodyHandler.class);
		if (!registry.containsBeanDefinition(apiResponseBeanName)) {
			definition = regManager.createBeanDefinition(ApiResponseBodyHandler.class, null, null, null);
			definition.getConstructorArgumentValues()
					.addGenericArgumentValue(new RuntimeBeanReference(handlerBeanName));
			definition.getConstructorArgumentValues().addGenericArgumentValue(
					annoAttrs.getStringArray(EnableAutumnApiResponseBody.API_CONTROLLER_PACKAGES_ATTRIBUTE_NAME));
			definition.getConstructorArgumentValues().addGenericArgumentValue(status);
			regManager.registerBean(apiResponseBeanName, definition);
		}
	}
}
